home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / tags18.zip / WILDFILE.C < prev    next >
C/C++ Source or Header  |  1992-01-06  |  10KB  |  356 lines

  1. /*
  2.  EPSHeader
  3.  
  4.    File: wildfile.c
  5.    Author: J. Kercheval
  6.    Created: Thu, 03/14/1991  21:49:02
  7. */
  8. /*
  9.  EPSRevision History
  10.  
  11.    J. Kercheval  Sat, 03/16/1991  15:48:38  add and use FileInfo struct
  12.    J. Kercheval  Sat, 03/16/1991  20:30:52  add status byte and '.' checking
  13.    J. Kercheval  Sat, 03/16/1991  22:50:42  _FA_NORMAL files unique, similar to _FA_READONLY behavior
  14.    J. Kercheval  Thu, 03/28/1991  21:23:37  move DOT_LAST to find_firstfile
  15.    J. Kercheval  Sun, 03/31/1991  14:31:15  change '/' to '\\' in path
  16.    D. Kirschbaum Mon, 05/13/1991  16:42:00  Minor Turbo C changes v1.14
  17.    F.C. Smith    Sat, 01/04/1992  (late)    allow d: in splitpath(),
  18.                                             required d:\ previously.
  19.    J. Kercheval  Mon, 01/06/1992  22:00:08  use general match code (ifdef'd)
  20. */
  21.  
  22. #include <stdlib.h>
  23. #include <string.h>
  24.  
  25. #include "wildfile.h"
  26. #include "match.h"
  27.  
  28. #ifndef __TURBOC__
  29. #define findfirst(n, a, s) _dos_findfirst(n, s, a)
  30. #define findnext _dos_findnext
  31. #else                           /* __TURBOC__ */
  32. #include <ctype.h>              /* toupper() v1.14 */
  33. #endif
  34.  
  35. #define DOT_LAST 0x01           /* set status byte if last char in pattern is
  36.                                  * '.' */
  37.  
  38. void splitpath(FileInfo * ff);
  39.  
  40.  
  41. /*----------------------------------------------------------------------------
  42.  *
  43.  * find_firstfile()
  44.  *
  45.  ---------------------------------------------------------------------------*/
  46.  
  47. BOOLEAN find_firstfile(FileInfo * ff)
  48. {
  49.     char path[MAXPATH + 1];     /* found file and path */
  50.     char *c;                    /* temporary pointer variable */
  51.  
  52.     int error_return;           /* error return from is_valid_pattern */
  53.  
  54.     BOOLEAN found;              /* looping flag */
  55.     BOOLEAN dot_found;          /* '.' character checking */
  56.  
  57.     /* empty strings are bummers, aren't they? */
  58.     if (!*(ff->file_pattern)) {
  59.         return FALSE;
  60.     }
  61.  
  62.     /* convert to upper case */
  63.     c = ff->file_pattern;
  64.     while (*c) {
  65.         *c = (char) toupper(*c);
  66.  
  67.         /* if the last pattern char is '.' then set status byte correctly */
  68.         if (*c == '.')
  69.             ff->status |= DOT_LAST;
  70.         else
  71.             ff->status &= ~DOT_LAST;
  72.  
  73.         c++;
  74.     }
  75.  
  76.     /* check for valid pattern string */
  77.     if (!is_valid_pattern(ff->file_pattern, &error_return)) {
  78.         return FALSE;
  79.     }
  80.  
  81.     /* copy the path portion of the pattern to file_path */
  82.     splitpath(ff);
  83.  
  84.     /* create the search path */
  85.     strcpy(path, ff->file_path);
  86.     strcat(path, "*.*");
  87.  
  88.     /* check that the search path will not be too long */
  89.     if (strlen(path) > MAXPATH) {
  90.         return FALSE;
  91.     }
  92.  
  93.     /* obtain the first file conforming to path */
  94.     if (findfirst(path, &(ff->file), (ff->file_attributes) & ~_FA_NORMAL)) {
  95.         return (FALSE);
  96.     }
  97.  
  98.     /* if the file name is empty we want it not */
  99.     if (!*(ff->file.name)) {
  100.         return (FALSE);
  101.     }
  102.  
  103.     /* init looping variable */
  104.     found = FALSE;
  105.  
  106.     /* Build path and file name needed for validation */
  107.     strcpy(path, ff->file_path);
  108.     strcat(path, ff->file.name);
  109.  
  110.     /* Check for '.' if required */
  111.     if (ff->status & DOT_LAST) {
  112.  
  113.         /* init looping variables */
  114.         dot_found = FALSE;
  115.         c = ff->file.name;
  116.  
  117.         /* see if file has extension and give it '.' if not */
  118.         while (*c) {
  119.             if (*c == '.')
  120.                 dot_found = TRUE;
  121.             c++;
  122.         }
  123.         if (!dot_found)
  124.             strcat(path, ".");
  125.     }
  126.  
  127.     /* Verify name and attribute wanted for files */
  128.     if (match(ff->file_pattern, path)) {
  129.  
  130.         if (!ff->file.attributes) {
  131.             if (ff->file_attributes & _FA_NORMAL) {
  132.                 found = TRUE;
  133.             }
  134.         }
  135.         else {
  136.             if (ff->file_attributes & ff->file.attributes) {
  137.                 found = TRUE;
  138.             }
  139.         }
  140.     }
  141.  
  142.     while (!found) {
  143.  
  144.         /* obtain the next file comforming to path */
  145.         if (findnext(&(ff->file))) {
  146.             return (FALSE);
  147.         }
  148.  
  149.         /* if the file name is empty we want it not */
  150.         if (!*(ff->file.name)) {
  151.             return (FALSE);
  152.         }
  153.  
  154.         /* Build path and file name needed for validation */
  155.         strcpy(path, ff->file_path);
  156.         strcat(path, ff->file.name);
  157.  
  158.         /* Check for '.' if required */
  159.         if (ff->status & DOT_LAST) {
  160.  
  161.             /* init looping variables */
  162.             dot_found = FALSE;
  163.             c = ff->file.name;
  164.  
  165.             /* see if file has extension and give it '.' if not */
  166.             while (*c) {
  167.                 if (*c == '.')
  168.                     dot_found = TRUE;
  169.                 c++;
  170.             }
  171.             if (!dot_found)
  172.                 strcat(path, ".");
  173.         }
  174.  
  175.         /* Verify name and attribute wanted for files */
  176.         if (match(ff->file_pattern, path)) {
  177.  
  178.             if (!ff->file.attributes) {
  179.                 if (ff->file_attributes & _FA_NORMAL) {
  180.                     found = TRUE;
  181.                 }
  182.             }
  183.             else {
  184.                 if (ff->file_attributes & ff->file.attributes) {
  185.                     found = TRUE;
  186.                 }
  187.             }
  188.         }
  189.     }
  190.  
  191.     return (TRUE);
  192. }
  193.  
  194.  
  195. /*----------------------------------------------------------------------------
  196.  *
  197.  * splitpath() is a helper function to isolate the pattern from the path.
  198.  * The parameter r gets the path portion of the pattern string p.
  199.  *
  200.  ---------------------------------------------------------------------------*/
  201.  
  202. void splitpath(FileInfo * ff)
  203. {
  204.     char *last_slash, *c, oldchar;
  205.  
  206.     /* init last_slash and c */
  207.     c = last_slash = ff->file_pattern;
  208.     last_slash--;
  209.  
  210.     /* loop through and find the beginning of the pattern or end of string */
  211.     while (*c && *c != '[' && *c != '*' && *c != '?') {
  212.  
  213.         /* change '/' to '\' */
  214.         if (*c == '/') {
  215.             *c = '\\';
  216.         }
  217.  
  218.         /* FCS 01-04-92 add the test for ':' */
  219.         /* if c is a '\' then remember where it is */
  220.         if (*c == '\\' || *c == ':') {
  221.             last_slash = c;
  222.         }
  223.  
  224.         /* move to next char in pattern */
  225.         c++;
  226.     }
  227.  
  228.     /* move to next char beyond '\' or to beginning of string */
  229.     last_slash++;
  230.  
  231.     /* store character and make it end of string for now */
  232.     oldchar = *last_slash;
  233.     *last_slash = '\0';
  234.  
  235.     /* copy the beginning of the path to return value */
  236.     strcpy(ff->file_path, ff->file_pattern);
  237.  
  238.     /* restore character */
  239.     *last_slash = oldchar;
  240. }
  241.  
  242.  
  243. /*----------------------------------------------------------------------------
  244.  *
  245.  * find_nextfile()
  246.  *
  247.  ---------------------------------------------------------------------------*/
  248.  
  249. BOOLEAN find_nextfile(FileInfo * ff)
  250. {
  251.     char path[MAXPATH + 1];     /* full filename and path for pattern
  252.                                  * checking */
  253.     char *c;                    /* tempory pointer variable */
  254.  
  255.     BOOLEAN found;              /* looping flag */
  256.     BOOLEAN dot_found;          /* '.' character checking */
  257.  
  258.     found = FALSE;
  259.  
  260.     while (!found) {
  261.  
  262.         /* obtain the next file comforming to path */
  263.         if (findnext(&(ff->file))) {
  264.             return (FALSE);
  265.         }
  266.  
  267.         /* if the file name is empty we want it not */
  268.         if (!*(ff->file.name)) {
  269.             return (FALSE);
  270.         }
  271.  
  272.         /* Build path and file name needed for validation */
  273.         strcpy(path, ff->file_path);
  274.         strcat(path, ff->file.name);
  275.  
  276.         /* Check for '.' if required */
  277.         if (ff->status & DOT_LAST) {
  278.  
  279.             /* init looping variables */
  280.             dot_found = FALSE;
  281.             c = ff->file.name;
  282.  
  283.             /* see if file has extension and give it '.' if not */
  284.             while (*c) {
  285.                 if (*c == '.')
  286.                     dot_found = TRUE;
  287.                 c++;
  288.             }
  289.             if (!dot_found)
  290.                 strcat(path, ".");
  291.         }
  292.  
  293.         /* Verify name and attribute wanted for files */
  294.         if (match(ff->file_pattern, path)) {
  295.  
  296.             if (!ff->file.attributes) {
  297.                 if (ff->file_attributes & _FA_NORMAL) {
  298.                     found = TRUE;
  299.                 }
  300.             }
  301.             else {
  302.                 if (ff->file_attributes & ff->file.attributes) {
  303.                     found = TRUE;
  304.                 }
  305.             }
  306.         }
  307.     }
  308.  
  309.     return (TRUE);
  310. }
  311.  
  312.  
  313. #ifdef TEST
  314.  
  315. /*
  316.  * The test loop expects the first input parameter on the command line to be
  317.  * the attributes desired in hex format (ie. 0x3f) and the following
  318.  * parameters to be the search path/file name.  Will output the names of all
  319.  * files which match the attributes wanted and the search path/file names. 
  320.  */
  321.  
  322. #include <stdio.h>
  323.  
  324. int main(int argc, char *argv[])
  325. {
  326.     FileInfo ff;
  327.  
  328.     unsigned int tmp;
  329.  
  330.     /* parse the attribute from the command line */
  331.     sscanf(argv[1], "%x", &tmp);
  332.     ff.file_attributes = (unsigned char) tmp;
  333.  
  334.     /* trace down the argument list until all file specs are parsed */
  335.     argc--;
  336.     argv++;
  337.     argc--;
  338.     argv++;
  339.     while (argc > 0) {
  340.         strcpy(ff.file_pattern, *argv);
  341.  
  342.         if (find_firstfile(&ff)) {
  343.             printf("File: %s%s\n", ff.file_path, ff.file.name);
  344.         }
  345.  
  346.         while (find_nextfile(&ff)) {
  347.             printf("File: %s%s\n", ff.file_path, ff.file.name);
  348.         }
  349.         argc--;
  350.         argv++;
  351.     }
  352.     return (0);
  353. }
  354.  
  355. #endif
  356.